package com.corejsf;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.Resource;
import javax.inject.Named; 
   // or import javax.faces.bean.ManagedBean;
import javax.enterprise.context.SessionScoped; 
   // or import javax.faces.bean.SessionScoped;
import javax.sql.DataSource;

@Named("user") // or @ManagedBean(name="user")
@SessionScoped
public class UserBean implements Serializable {
  private String name;
  private String password;
  private int count;
  private boolean loggedIn;
  private Logger logger=Logger.getLogger("com.corejsf");
  
  @Resource(name="jdbc/flohmarkt")
  private DataSource ds;
  
  public String getName() { return name; }
  public void setName(String newValue) { name = newValue; }
  
  public String getPassword() { return password; }
  public void setPassword(String newValue) { password = newValue; }
  
  public int getCount() { return count; }
  
  public String login() {
    try {
      doLogin();
    }
    catch (SQLException ex) {
      logger.log(Level.SEVERE, "login failed", ex);
      return "internalError";
    }
    if (loggedIn)
      return "loginSuccess";
    else
      return "loginFailure";
  }
  
  public String logout() {
    loggedIn = false;
    return "login";
  }
  
  public void doLogin() throws SQLException {
    if(ds==null) throw new SQLException("No data source");
    Connection conn = ds.getConnection();
    if(conn==null) throw new SQLException("No connection");
    try{
      conn.setAutoCommit(false);
      boolean committed = false;
      try{
        PreparedStatement passwordQuery = conn.prepareStatement(
            "SELECT passwd, logincount from Credentials WHERE username = ?");
        passwordQuery.setString(1, name);
        ResultSet result = passwordQuery.executeQuery();
        if(!result.next()) return;
        String storedPassword=result.getString("passwd");
        loggedIn=password.equals(storedPassword);
        count=result.getInt("logincount");
        PreparedStatement updateCounterStat=conn.prepareStatement(
            "UPDATE Credentials SET logincount = logincount + 1"
            + " WHERE USERNAME = ?");
        updateCounterStat.setString(1, name);
        updateCounterStat.executeUpdate();
        
        conn.commit();
        committed=true;
      } finally{
        if(!committed) conn.rollback();
      }
    }
    finally {conn.close();}
  }
  
  public void setImage(BufferedImage img) throws SQLException {
    if(ds==null) throw new SQLException("No data source");
    Connection conn=ds.getConnection();
    if(conn==null) throw new SQLException("No connection");
    Blob blob=null;
    try{
      conn.setAutoCommit(false);
      boolean committed=false;
      try{
        blob=conn.createBlob();
        ObjectOutputStream oos=new ObjectOutputStream(blob.setBinaryStream(1));
        oos.writeObject(img);
        oos.close();
        PreparedStatement bildrein=conn.prepareStatement(
            "UPDATE Credentials SET foto = ? WHERE USERNAME = ?");
        bildrein.setBlob(1, blob);
        bildrein.setString(2, name);
        bildrein.executeUpdate();
        conn.commit();
        committed=true;
      } catch(IOException ex){
      } finally{
        if(!committed) conn.rollback();
      }
    }
    finally{
      if(blob!=null) blob.free();
      conn.close();
    }
  }

  public BufferedImage holeImage() throws SQLException{
    if(ds==null) throw new SQLException("No data source");
    Connection conn=ds.getConnection();
    if(conn==null) throw new SQLException("No connection");
    Blob blob=null;
    BufferedImage img=null;
    try{
      PreparedStatement bildraus=conn.prepareStatement(
          "SELECT foto FROM Credentials WHERE name = ?");
      bildraus.setString(1, name);
      ResultSet res=bildraus.executeQuery();
      if(res.next()){
        blob=res.getBlob(1);
        ObjectInputStream ois=new ObjectInputStream(blob.getBinaryStream());
        img=(BufferedImage)ois.readObject();
      }
    } catch(IOException ex){
    } catch(ClassNotFoundException ex){
      System.out.println("Geht nicht.");
    } finally{
      if(blob!=null) blob.free();
      conn.close();
    }
    return img;
  }
}